<?php

class mod {
  public static $current = 'system';
  public static $mods = array();
  public static $dir = 'mod/';
  
  public static function init() {
    $sql = "SELECT * FROM `mods`";
    $mod = db::q( $sql );
    while ( $mod->exists() ) {
      self::$mods[ $mod->mod ] = $mod->assoc();
    }
  }
  
  public static function exec( $call_string ) {
    $mod = new Module( $call_string );
    return $mod->exec();
  }
  
  
  public static function exists( $call_string ) {
    $name = self::get_name($call_string);
    // if module exists and enabled
    return array_key_exists( $name, self::$mods )
        && self::$mods[ $name ]['enabled']
        && file_exists( 'mod/'.replace_once( '.', '/', $call_string ).'.php' ) ;
  }
  
  
  public static function toggle_enabled( $mod ) {
    $sql = "UPDATE `mods` SET `enabled` = NOT `enabled` WHERE `mod`='::1'";
    db::q( $sql, $mod )->success() && self::$mods[ $mod ]['enabled'] = !self::$mods[ $mod ]['enabled'];
  }
  
  public static function enable( $mod ) {
    $sql = "UPDATE `mods` SET `enabled`='1' WHERE `mod`='::1'";
    db::q( $sql, $mod )->success() && self::$mods[ $mod ]['enabled'] = true;
  }
  
  public static function disable( $mod ) {
    $sql = "UPDATE `mods` SET `enabled`='0' WHERE `mod`='::1'";
    db::q( $sql, $mod )->success() && self::$mods[ $mod ]['enabled'] = false;
  }

  public static function check_filesystem( $mod ) {
    return
        is_dir(self::$dir.$mod) &&
        file_exists(self::$dir.$mod.'/'.$mod .'.php') &&
        file_exists(self::$dir.$mod.'/about.php');
  }
  
  
  public static function get_name( &$call_string ) {
    $dot = strpos( $call_string, '.' );
    if ( $dot === false ) {
      $name = $call_string;
      $call_string = $name . '.' . $name;
      return $name;
    }
    return substr( $call_string, 0, $dot );
  }
  
}



class Module {
  public $name    = 'generic';
  public $param   = array();
  /**
   * Content element that called module execution
   * @var Content
   */
  public $caller;
  protected $data = null;
  protected $filename;

  public function __construct( $call_string ) {
    // get module name
    $this->name = mod::get_name( $call_string );
    // if module exists
    if ( !array_key_exists( $this->name, mod::$mods ) ) {
      trigger_error( 'Module "'.$this->name.'" not registered.', E_USER_NOTICE );
      return;
    }
    // if module is enabled
    if ( !mod::$mods[$this->name]['enabled'] ) {
      trigger_error( 'Module "'.$this->name.'" not enabled.', E_USER_NOTICE );
      return;
    }
    // if requested file exists in the module
    if ( !file_exists( $this->filename='mod/'.replace_once( '.', '/', $call_string ).'.php' ) ) {
      trigger_error( 'Component "'.$call_string.'" of module "'.$this->name.'" not found.', E_USER_NOTICE );
      return;
    }
    $this->data = new Atom( mod::$mods[$this->name] );
    if ( $this->name!==$call_string ) {
      @include_once 'mod/'.replace_once( '.', '/', $call_string ).'.class.php';
    } else {
      $call_string = $this->name.'.'.$this->name;
    }
    @include_once 'mod/'.$this->name.'/class.php';
  }
  
  
  public function exec() {
    if ( is_a( $this->data, 'Atom' ) ) {
      // change current module
      $caller = mod::$current;
      mod::$current = $this->name;
      ob_start();
      // call module
      include $this->filename;
      mod::$current = $caller;
      return ob_get_clean();
    }
    return null;
  }
  
  
  public function param( $name, $value=null ) {
    if ( $value === null ) {
      if ( array_key_exists( $name,  $this->param ) ) {
        return $this->param[$name];
      }
      return null;
    } else {
      return $this->param[$name] = $value;
    }
  }
  
}



mod::init();
?>